#ifndef __CE_UTILS_NODESCANNER_H__
#define __CE_UTILS_NODESCANNER_H__

#include <export.h>

struct iClipper;
struct iDevice;
class ceCamera;
class ceEntityNode;
class ceGroupNode;
class ceLODNode;
class ceNode;
class cePortal;
class ceProjector;
class ceRenderBucket;
struct ceRenderEnvironment;
class ceScene;
class ceSector;

/**
 * \addtogroup utils
 * @{
 */
/**
 * @brief Utility class for traversing the scene tree an filling a ceRenderBucket
 */
class CE_API ceNodeScanner
{
private:
  enum CollectShadowCaster
  {
    CSC_None      = 0,
    CSC_NonCaster = 1,
    CSC_Caster    = 2,
    CSC_All       = CSC_NonCaster | CSC_Caster
  };

  bool TestPortal (cePortal* portal, iClipper* clipper);

  void Scan (ceEntityNode* entity, iClipper* clipper);
  void Scan (ceLODNode* lod, iClipper* clipper);
  void Scan (ceNode* node, iClipper* clipper);
  void Scan (ceSector* sector, iClipper* clipper);

  iDevice*              _device;
  ceRenderEnvironment*  _env;
  ceRenderBucket*       _bucket;
  bool                  _update;
  bool                  _collectEffectCameras;
  bool                  _collectLights;
  unsigned              _collectShadowCaster;
public:
  ceNodeScanner(iDevice* device = 0, ceRenderBucket* bucket = 0, ceRenderEnvironment* env = 0);

  void SetUpdate (bool update);
  void SetCollectEffectCameras (bool collect);
  void SetCollectLights (bool collect);
  void SetCollectShadowCasters (bool caster, bool nonCaster);

  void SetDevice (iDevice* device);
  void SetRenderBucket (ceRenderBucket* bucket);
  void SetRenderEnvironment (ceRenderEnvironment* env);

  void Scan (ceNode* node, const ceCamera& camera, const ceProjector& projector, unsigned frame);
  void Scan (ceScene* scene, const ceCamera& camera, const ceProjector& projector, unsigned frame);


};

/** @} */

#endif /* ! __CE_UTILS_NODESCANNER_H__ */
